
var Pool = cc.Class({
    name: 'Pool',
    properties: {
        initNum: {
            default: 1,
            type: cc.Integer,
            min: 1,
            tooltip: "初始化节点池的预制数量, 大于0的整数",
        },
        prefab: {
            default: null,
            type: cc.Prefab,
            tooltip: "用来生成节点池的预制体",
        }
    }
});

var self = null;
cc.Class({
    extends: cc.Component,

    properties: {
        prefabArr: {
            default: [],
            type: Pool,
            tooltip: "输入要生成的节点池的个数",
        },
    },

    onLoad() {
        self = this;
        this.allPoolArr = [];
        for(var i = 0; i < this.prefabArr.length; i++){
            if(this.prefabArr[i].prefab === null){
                console.error("缺少预制体!!!");
            }else{
                this.commonFunction(i);
            }
        }    
    },

    commonFunction(i){
        var initNum = this.prefabArr[i].initNum;
        var prefabName = this.prefabArr[i].prefab.name;
        //初始化节点池
        this[prefabName + "Pool"] = this.initPool(initNum, this.prefabArr[i].prefab);
        //取节点
        this["get" + prefabName] = function(){
            return this.getNode(this[prefabName + "Pool"], this.prefabArr[i].prefab);
        }.bind(this);
        //放回节点
        this["put" + prefabName] = function(node){
            this.putNode(this[prefabName + "Pool"], node);
        }.bind(this);
    },


    initPool(num, prefab){
        var nodePool = new cc.NodePool();
        for (var i = 0; i < num; ++i) {
            var ins = cc.instantiate(prefab);
            nodePool.put(ins); 
        }
        this.allPoolArr.push(nodePool);
        console.log("初始化节点池完成,节点池个数",  this.allPoolArr.length);
        return nodePool;
    },

    getNode(nodePool, prefab){
        var node = null;
        if(nodePool.size() > 0){
            node = nodePool.get();
        }
        else{
            console.warn(prefab.name + "重新创建!!!");
            node = cc.instantiate(prefab);
        }
        return node;
    },

    putNode(nodePool, node){
        nodePool.put(node);
        //console.log(node.name + "节点池数量:", nodePool.size());
    },

    onDestroy(){
        for(var i = 0; i < this.allPoolArr.length; i++){
            this.allPoolArr[i].clear();
        }
    }
});

/**
 * 注意：需要挂在场景节点上使用
 * 
 * 使用方法：将脚本挂在任意节点上(建议挂在scene跟canvas同级的节点上，在canvas上面，能保证最先初始化)，输入你要生成节点池的个数，拉取对应的预制，输入初始化数量，节点池就完成了 
 *  
 * 例如拉取一个叫 ball 的预制，设置初始化数量为100  
 * 方法：  
 * 1.获取节点： GPool.get("预制名字")，如：GPool.get("ball");  
 * 2.放回节点： GPool.put("预制名字", node)，如：GPool.put("ball", node);  
 * 3.此脚本摧毁的时候会自动销毁所有节点池  
 * 提示：把节点放回节点池的时候，不会自动把节点恢复到初始状态，所以，应该先自己对节点进行“恢复出厂”操作，然后放回节点池
 */
var GPool = {
    /**
     * 根据预制的名字从对应的节点池获取一个节点
     * @param {String} prefabName 预制的名字
     */
    get(prefabName){
        return self["get" + prefabName]();
    },

    /**
     * 将一个节点回收到对应的节点池
     * @param {String} prefabName 预制的名字
     * @param {Node} node 要回收的节点
     */
    put(prefabName, node){
        self["put" + prefabName](node);
    }
};

window.GPool = GPool;
